#include "thread/timer.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/mutex.h"
#include "thread/executor.h"

Mutex Timer::mutex_;

void Timer::Handler(sigval_t value) {
  ((Closure*) value.sival_ptr)->Run();
}

bool Timer::AddAfter(int64 usec,
    Closure* closure) {
  WriteLock lock(&mutex_);
  sigevent se;
  timer_t timerid;
  se.sigev_notify = SIGEV_THREAD;
  se.sigev_value.sival_ptr = closure;
  se.sigev_notify_function = Handler;
  se.sigev_notify_attributes = NULL;
  if (timer_create(CLOCK_REALTIME,
        &se,
        &timerid) == -1) {
    perror("Failed to create timer");
    return false;
  }
  struct itimerspec its;
  its.it_value.tv_sec = usec / 1000000;
  its.it_value.tv_nsec = usec % 1000000;
  its.it_interval.tv_sec = 0;
  its.it_interval.tv_nsec = 0;
  if (timer_settime(timerid, 0, &its, NULL) == -1) {
    perror("set timer");
    return false;
  }
  return true;
}
